package com.zhyl.detectibrary.util;


import android.content.Context;
import android.content.res.AssetManager;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.text.SimpleDateFormat;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class AppLisenseHelper {
    public static boolean verifyLicence(Context context) throws Exception {
        String appPackageName = context.getPackageName();
        String licenceFile = "lisense.dat";
        String pwd = appPackageName+"_6339889";
        String licenceContent = getFileContent(context,licenceFile,"licence_info.txt",pwd);
        String decodeLicenceInfo = new String(Base64.decode(licenceContent));
        JSONObject licenceObject = JSONUtil.parseObj(decodeLicenceInfo);
        String licencePackageName = licenceObject.get("packageName").toString();
        String companyName = licenceObject.get("companyName").toString();
        String startDate = licenceObject.get("startDate").toString();
        String endDate = licenceObject.get("endDate").toString();
        String signature = licenceObject.get("signature").toString();
        String licenceInfo = String.format("%s|%s|%s|%s", appPackageName, companyName, startDate, endDate);
        InputStream keyInputSteam = getFileInputStream(context,licenceFile,"publicKey.pem",pwd);
        boolean b = SignatureVerifier.verifySignatureWithBase64ByPubkey(licenceInfo, signature, keyInputSteam);
        if (!b) {
            throw new RuntimeException("非法的签名");
        }
        if(!appPackageName.equalsIgnoreCase(licencePackageName)){
            throw new RuntimeException("非法的授权");
        }
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        if(DateUtil.date().getTime() > sf.parse(endDate).getTime()){
            throw new RuntimeException("授权已过期, 有效期["+endDate+"]");
        }
        return b;
    }

    public static String getFileContent(Context context,String zipFileName, String textFileName,String password) throws IOException {
        InputStream in = getFileInputStream(context,zipFileName,textFileName,password);
        return readStream(in);
    }
    /**
     * 从assets文件夹中读取ZIP文件，并获取其中的某个文本文件内容
     *
     * @param zipFileName  ZIP文件名
     * @param textFileName 要读取的文本文件名
     * @return 文本文件内容
     */
    public static InputStream getFileInputStream(Context context,String zipFileName, String textFileName,String password) {
        try {
            AssetManager assetManager = context.getAssets();
            InputStream inputStream = assetManager.open(zipFileName);

            // 将ZIP文件复制到内部存储
            File zipFile = new File(context.getCacheDir(), zipFileName);
            OutputStream outputStream = new FileOutputStream(zipFile);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }
            outputStream.close();
            inputStream.close();

            // 使用zip4j读取ZIP文件中的文本文件内容
            ZipFile zip = new ZipFile(zipFile);
            if (zip.isEncrypted()) {
                zip.setPassword(password.toCharArray());
            }
            FileHeader fileHeader = zip.getFileHeader(textFileName);
            if (fileHeader != null) {
                InputStream fileInputStream = zip.getInputStream(fileHeader);
                return fileInputStream;
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 从InputStream中读取内容到字符串
     *
     * @param inputStream 输入流
     * @return 字符串内容
     */
    private static String readStream(InputStream inputStream) throws IOException {
        StringBuilder content = new StringBuilder();
        try (Reader reader = new InputStreamReader(inputStream);
             BufferedReader bufferedReader = new BufferedReader(reader)) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                content.append(line);
                content.append("\n");
            }
        }
        return content.toString();
    }

}
